//
//  CoGeOffscreenRenderer.m
//  CoGeOpenSource
//
//  Created by Tamas Nagy on 14/11/13.
//  Copyright (c) 2013 home. All rights reserved.
//

#import "CoGeOffscreenRenderer.h"
#import "CoGeRenderer.h"
#import <OpenGL/CGLMacro.h>

@implementation CoGeOffscreenRenderer

@synthesize creatorThread;
@synthesize compositionFilePath;

-(id)initWithComposition:(QCComposition *)composition {

    if (self = [super init]) {
        
        markedToRelease = NO;
        
        isUsingFallbackRenderer = NO;
        
        //we should use kCGColorSpaceGenericRGB, or QCRendere will crash
        //especially with NULL on 10.6
        CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
        
        @try {
            renderer = [[QCRenderer alloc] initWithComposition:composition colorSpace:colorSpace];
        }
        @catch (NSException *exception) {
            NSLog(@"cannot create CoGeOffscreenRenderer renderer, fallback to CoGeRenderer");
        }
        
        
        CGColorSpaceRelease(colorSpace);
        
        if (!renderer) {
            
            //we should have a fallback here
            //since depending on the contents of the offscreen composition
            //its possible we need to use a CGL based renderer here
            
            
            renderer = [[CoGeRenderer alloc] initCoGeRendererWithPixelFormat:nil composition:composition shareContext:nil];
        
            isUsingFallbackRenderer = YES;
        }
        
        self.creatorThread = [NSThread currentThread];

        return self;
    }
    
    return nil;
}

#pragma mark Inherated methods
- (void)renderAtTime:(NSTimeInterval)time withArguments:(NSDictionary *)arguments {
    if (isUsingFallbackRenderer) {
        [renderer renderAtTime:time withArguments:nil];
    } else {
        [renderer renderAtTime:time arguments:nil];
    }
}

- (QCComposition*) composition {
	return [renderer composition];
}

#pragma mark Protocol methods

- (BOOL)setValue:(id)value forInputKey:(NSString *)key {
	
	return [renderer setValue:value forInputKey:key];
}

- (id)valueForInputKey:(NSString *)key {
	return [renderer valueForInputKey:key];
}

- (id)valueForOutputKey:(NSString *)key {
	return [renderer valueForOutputKey:key];
}

- (id) valueForOutputKey:(NSString*)key ofType:(NSString*)type {
	return [renderer valueForOutputKey:key ofType:type];
}

- (NSDictionary *)attributes {
	return [renderer attributes];
}

- (NSArray *)inputKeys {
	return [renderer inputKeys];
}

- (NSArray *)outputKeys {
	return [renderer outputKeys];
}

- (id) propertyListFromInputValues {
	return [renderer propertyListFromInputValues];
}

- (void) setInputValuesWithPropertyList:(id)plist {
	[renderer setInputValuesWithPropertyList:plist];
}

- (NSMutableDictionary*)userInfo {
	return [renderer userInfo];
}


//a really handy stuff
//which makes our QCRenderer always being released
//on the thread its created
-(void)cleanUpOnRenderingThread {
    
    if (!markedToRelease) {
        
        markedToRelease = YES;
        
        //waitUntilDone should be NO
        //because creatorThread may not the same than current
        
        if (self.creatorThread != nil) {
            
            if (![self.creatorThread isEqualTo:[NSThread currentThread]]) {
                
                NSLog(@"releasing offscreen QCRenderer in the good thread...");
                
                [self performSelector:@selector(cleanUpRenderer) onThread:self.creatorThread withObject:nil waitUntilDone:NO];
                
            } else {
                
                [self cleanUpRenderer];
                
            }
            
        } else {
            
            NSLog(@"creatorThread is nil!");
            
            [self cleanUpRenderer];
            
        }
        
        
        
        
    }
    
}

-(void)cleanUpRenderer {
    
    //   NSLog(@"cleanUpRenderer start");
    
	[[NSNotificationCenter defaultCenter] removeObserver:self];

	
    if (renderer != nil) {
        
        if (isUsingFallbackRenderer) {
            
            [renderer cleanUpRenderer];
        }
        
        [renderer release];
        renderer = nil;
        
    }
    
    
    
    
    if (compositionFilePath != nil) {
        
        [compositionFilePath release];
        compositionFilePath = nil;
        
    }
    
    
    
    
}

#pragma mark Dealloc

-(void)dealloc {
    
    //   NSLog(@"CoGeRenderer release, retain count: %d", (int)[renderer retainCount]);
	NSLog(@"dealloc CoGeOffscreenRenderer, finally.");
    
    if (renderer != nil) {
        
        NSLog(@"renderer still not deallocated when deallocating CoGeOffscreenRenderer...");
        [renderer release];
    }
    
	[super dealloc];
}



@end
